﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.XPath;
using log4net;
using Sherwood.Content.Contracts;

namespace Sherwood.Content.UpdateServices.Attachments
{
    public class AttachmentXmlUpdater<TAttachmentMeta> : MetaUpdaterBase<TAttachmentMeta>
        where TAttachmentMeta : class, IAttachmentMeta, new()
    {
        private static readonly ILog Log = LogManager.GetLogger(typeof(AttachmentXmlUpdater<TAttachmentMeta>));

        private readonly IAttachmentPersister _attachmentPersister;

        public AttachmentXmlUpdater(IMetaRepository metaRepository, IAttachmentPersister attachmentPersister) 
            : base(metaRepository)
        {
            _attachmentPersister = attachmentPersister;
        }

        protected override void UpdateMeta(TAttachmentMeta meta, XmlReader reader)
        {
            var existingAttachments = meta.GetAttachments().ToDictionary(a => a.ReferenceId);

            var xpath = new XPathDocument(reader).CreateNavigator();
            foreach (XPathNavigator attachmentXml in xpath.Select("*/attachment"))
            {
                var url = attachmentXml.GetAttribute("url", string.Empty);
                var fileExtension = attachmentXml.GetAttribute("fileExtension", string.Empty);
                if (!string.IsNullOrEmpty(url))
                {
                    var referenceId = attachmentXml.GetAttribute("referenceId", string.Empty);
                    if (string.IsNullOrEmpty(referenceId))
                        referenceId = url;

                    IAttachment attachment;
                    if (!existingAttachments.TryGetValue(referenceId, out attachment))
                        _attachmentPersister.AddAttachment(meta, referenceId, url, fileExtension);
                    else
                    {
                        existingAttachments.Remove(referenceId);
                        _attachmentPersister.UpdateAttachment(meta, attachment, url, fileExtension);
                    }
                }
            }

            foreach (var value in existingAttachments.Values)
                _attachmentPersister.DeleteAttachment(meta, value);
        }
    }
}
